
#include <pic18.h> 
#include "flash.h"
 
#define   BUFFER_SIZE	64

unsigned char buff[BUFFER_SIZE];

bit DO_NOT_INCREMENT;

#define   MASK 63

void zap(void)
{
	WREN=1;
	EECON2=0x55;
	EECON2=0xAA;
	WR=1;
	NOP();
	while(WR);
	WREN=0;
}

/* transfer a byte from RAM to internal flash register(s) */

void WriteTable(void)
{
	if(DO_NOT_INCREMENT)	// address is already loaded in TBLPTR, no pre-increment needed
	{
		DO_NOT_INCREMENT=0;
		asm("tblwt*");
	}
	else
		asm("tblwt+*");	// otherwise TBLPTR must be pre-incremented
}

/* write the bytes buffer to flash */

void WriteFlash( unsigned char* Buffer )
{
	unsigned char i;
#ifdef	DEBUG
	TBLPTRU = Memo;
	TXREG2 ='W';
	while ( !TRMT2 ) ;
	TXREG2 = TBLPTRU;
	while ( !TRMT2 ) ;
#endif

	if(DO_NOT_INCREMENT)
		TBLPTRL &= ~MASK;	// point to start of 8 byte panel
	for( i = 0; i < BUFFER_SIZE; i++ )
	{	
		TABLAT = Buffer[i];
		WriteTable();
	}
	zap();
}

//void ClearBuffer( void )
{	
	unsigned char i;

	for ( i = 0; i < BUFFER_SIZE; i++ )
	{
		buff[i] = 0xFF;
	}
}


void FlashWrite( unsigned long Address, unsigned char* Buffer )
{
	//unsigned char i;

	TBLPTRL = (unsigned char)Address;
	TBLPTRH = (unsigned char)(Address >> 8);
	TBLPTRU = (unsigned char)(Address >> 16);

/* 	for ( i = 0; i < 64; i++ ) */
/* 	{ */
/* 		buff[i] = Buffer[i]; */
/* 	} */
	DO_NOT_INCREMENT = 1;
	WriteFlash(Buffer);
}
 
void FlashRead( unsigned long Address, unsigned char* Buffer )
{
	unsigned char i;

	TBLPTRL = (unsigned char)Address;
	TBLPTRH = (unsigned char)(Address >> 8);
	TBLPTRU = (unsigned char)(Address >> 16);

	for ( i = 0; i < 64; i++ )
	{
		asm("tblrd*+");
		Buffer[i] = TABLAT;
	}
}
  
void FlashErase( unsigned long Address )
{
	TBLPTRL = (unsigned char)Address;
	TBLPTRH = (unsigned char)(Address >> 8);
	TBLPTRU = (unsigned char)(Address >> 16);

	EECON1=0x90;	// set up for flash erasure
	zap();
}
 
void RedirIntVector( void )
{
	FlashRead( 0, buff);
	
	//04EF02F0
	buff[8] = 0x04;
	buff[9] = 0xEF;
	buff[10] = 0x02; 
	buff[11] = 0xF0;
	
	FlashErase( 0 );
	
	FlashWrite(0, buff);
}
